<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <style>
      .demo {
        padding: 50px;
        border: 1px solid #000;
      }
    </style>
  </head>
  <body>
    <!-- 
      依赖注入主要操作就是操作 provide 与 inject 选项

      Provide

        对象语法
          provide: {
            key: value
          }
          
        函数语法
          provide() {
            return {
              key: value
            }
          }

      Inject

        数组语法：
          inject: ['key1', 'key2', 'key3']

        对象语法:
          inject: {
            /* 本地属性名 */ localMessage: {
              from: /* 注入来源名 */ 'message'

              default: /* 默认值 */ 'abcd'
            }
          }


      Inject 注入的数据规则
          一层一层往父级组件查找，如果查找到直接使用，最终找不到就是一个 undefined

      Provide 对象写法与 函数写法有什么区别：
          函数写法可以访问this

      Provide 提供的数据不是响应式的!

      如何让 Provide 提供的数据是响应式的呢？？？？？
          
          1. 提供一个函数下去，函数中返回数据
          2. 直接将当前组件的 this 提供下去
          3. Vue3 中，可以通过 组合式API 中的 computed 函数来提供数据下去


            
     -->

    <div id="app"></div>

    <script src="../lib/vue3.js"></script>
    <script>
      const app = Vue.createApp({
        template: `
          <div class="demo">
            <Parent />
          </div>
        `,

        data() {
          return {
            firstName: "李",
          };
        },

        // provide: {
        //   firstName: this.firstName,
        // },

        provide() {
          return {
            firstName: this.firstName,

            // 1. 提供一个函数下去
            getFirstName: () => {
              return this.firstName;
            },

            // 2. 提供当前组件实例下去
            root: this,

            // 3. Vue3 独有的，提供一个 computed 下去
            firstNameTwo: Vue.computed(() => this.firstName),
          };
        },
      });

      app.component("Parent", {
        // inject: ["firstName"],

        inject: {
          abcd: {
            from: "firstName",
          },

          getFirstName: {},

          root: {},

          firstNameTwo: {},
        },

        provide: {
          firstName: "张",
          money: 10,
        },

        template: `
          <div class="demo">
            <p>{{ abcd }}</p>
            <p>{{ getFirstName() }}</p>
            <p>{{ root.firstName }}</p>
            <p>{{ firstNameTwo }}</p>

            <Son />
          </div>
        `,
      });

      app.component("Son", {
        // 注入 provide 提供下来的数据
        // inject: ["firstName", "money", "house"],

        inject: {
          firstName: {},
          money: {},
          house: { default: "无" },
        },

        template: `
          <div class="demo">
            <p>firstName: {{ firstName }}</p>
            <p>money: {{ money }}</p>
            <p>house: {{ house }}</p>
          </div>
        `,
      });

      app.mount("#app");
    </script>
  </body>
</html>
